
using System;
using System.Reflection;
using System.Text;
using System.Collections;
using System.Collections.Specialized;
using Antu.Core.Services;

namespace Antu.Core.Ajax
{
    /// <summary>
    /// Provides methods to serialize and deserialize an object that implements IEnumerable.
    /// </summary>
    public class IEnumerableConverter : AbstractJavascriptConverter
    {
        SerializerService _SerializerService = (SerializerService)ServiceManager.Manager.GetService(typeof(SerializerService));
        /// <summary>
        /// Initializes a new instance of the <see cref="IEnumerableConverter"/> class.
        /// </summary>
        public IEnumerableConverter()
            : base()
        {
            allowInheritance = true;

            serializabletypeslist = new Type[] { typeof( IEnumerable ) };
        }

        /// <summary>
        /// Converts a .NET object into a JSON string.
        /// </summary>
        /// <param name="o">The object to convert.</param>
        /// <returns>Returns a JSON string.</returns>
        public override string Serialize( object o )
        {
            StringBuilder sb = new StringBuilder();
            Serialize( o , sb );
            return sb.ToString();
        }

        /// <summary>
        /// Serializes the specified o.
        /// </summary>
        /// <param name="o">The o.</param>
        /// <param name="sb">The sb.</param>
        public override void Serialize( object o , StringBuilder sb )
        {
            IEnumerable enumerable = o as IEnumerable;

            if ( enumerable == null )
                throw new NotSupportedException();

            bool b = true;

            sb.Append( "[" );

            foreach ( object obj in enumerable )
            {
                if ( b )
                {
                    b = false;
                }
                else
                {
                    sb.Append( "," );
                }

                sb.Append(_SerializerService.Serialize(obj));
            }

            sb.Append( "]" );
        }

        /// <summary>
        /// </summary>
        /// <param name="o"></param>
        /// <param name="t"></param>
        /// <param name="sb"></param>
        /// <returns></returns>
        public override bool TrySerializeValue( object o , Type t , StringBuilder sb )
        {
            if ( typeof( IDictionary ).IsAssignableFrom( t ) )
            {
                return false;
            }

            return base.TrySerializeValue( o , t , sb );
        }

        /// <summary>
        /// </summary>
        /// <param name="jso"></param>
        /// <param name="t"></param>
        /// <param name="o"></param>
        /// <returns></returns>
        public override bool TryDeserializeValue( IJavascriptObject jso , Type t , out object o )
        {
            if ( typeof( IDictionary ).IsAssignableFrom( t ) )
            {
                o = null;
                return false;
            }

            return base.TryDeserializeValue( jso , t , out o );
        }
    }
}
